home *** CD-ROM | disk | FTP | other *** search
- /*
- PixelFlipperINIT.c
- written in Think C 4.0 by Chris Sanchez
- Copyright ©1990 Chris Sanchez, All Rights Reserved
- */
-
- #include "PixelFlipper.h"
-
- /* Global Variables */
- long gOldGNETrap, gOldWNETrap;
- GDHandle gCurGDev; /* This is the current graphics device */
- PREFRec gPrefs; /* This is the preferences for the INIT */
- short gTempPerm; /* for the menu hook */
- Str255 gBitStr, gCursStr, gMenuStr;
-
- /* Prototypes */
- pascal char NewGNETrap( short theMask, EventRecord *theEvent );
- pascal char NewWNETrap( short theMask, EventRecord *theEvent, unsigned long sleep, RgnHandle mouseRgn );
- void main(void);
- /**********************************************************************************************
- Private Routines for PixelFlipper
- **********************************************************************************************/
- static pascal short HasDepth( GDHandle gd, short newDepth, short whichFlags, short newFlags )
- = {0x203C, 0x000A, 0x0014, 0xAAA2};
-
- static pascal short SetDepth( GDHandle gd, short newDepth,short whichFlags, short newFlags )
- = {0x203C, 0x000A, 0x0013, 0xAAA2};
-
- static Boolean keyIsDown(unsigned int k)
- /* -> k is a key code to check if being pressed.
- <- returns TRUE if the key is down.
- */
- { unsigned char km[16];
-
- GetKeys(km);
- return((km[k>>3] >> (k & 7)) & 1);
- }
-
- static GDHandle FindGDev()
- /* -> void. Takes no parameters.
- <- GDHandle. The handle to the graphics device that the mouse was down in.
- */
- { Point theMouse;
- GDHandle gdevs;
-
- GetMouse(&theMouse);
- for(gdevs = GetDeviceList();gdevs;gdevs = GetNextDevice(gdevs))
- if (TestDeviceAttribute(gdevs, screenDevice) && TestDeviceAttribute(gdevs, screenActive) && PtInRect(theMouse, &(**gdevs).gdRect))
- return gdevs;
- return GetGDevice(); /* just return the current device */
- }
-
- static GetColors( Boolean *mode, short *bits )
- /* -> mode, bits. The mode is the screen setting (0 = B&W, 1 = Color )
- bits is the pixel depth of the selected GDevice.
- <- returns nothing.
- */
- {
- gCurGDev = FindGDev(); /* always update the graphics device global */
- *mode = ((**gCurGDev).gdFlags & 1);
- *bits =(**(**gCurGDev).gdPMap).pixelSize;
- }
-
- static MakePerm(short theDepth, short theMode)
- /* -> theDepth, theMode. The theDepth and mode are the settings that the user
- has requested to be changed. These changes are made in the 'scrn' = 0 resource
- in the system file.
- <- returns nothing.
- */
- { short **screens, *scrn;
- short numCtl, numDevs, i, j, oldRef;
- Rect theRect, diffRect;
-
- #define kOffSetToRect 9
- #define kOffSetToMode 4
- #define kOffSetToFlag 6
- #define kOffSetToCtl 13
-
- oldRef = CurResFile();
- UseResFile(0); /*use the system file */
- theRect = (**gCurGDev).gdRect; /* the rect of the graphics devide we are in */
- if (!TestDeviceAttribute(GetDeviceList(), allInit)) return; /* were devices initalized from 'scrn 0' resource */
- if ((screens = Get1Resource('scrn', 0)) == NIL) return; /* can't find the scrn 0 resource */
- numDevs = **screens;
- scrn = *screens; /* Get a pointer if ints */
- scrn += 1; /* scrn now points to the beginning of the data */
- for (i=0;i < numDevs;i++){
- if (SectRect(&theRect,scrn + kOffSetToRect, &diffRect)){
- *(scrn + kOffSetToMode) = (**gCurGDev).gdMode;
- if (*(scrn + kOffSetToFlag) & 1){
- if (!theMode)
- *(scrn + kOffSetToFlag) ^= 1;
- }else
- if (theMode)
- *(scrn + kOffSetToFlag) |= 1;
-
- ChangedResource(screens);
- UpdateResFile(0);
- break;
- }else{ /* goto the next one, calculate the offset to the next device record */
- scrn += kOffSetToCtl;
- numCtl = *scrn;
- scrn +=1; /* now to the beginning of the control data. */
- for (j = 0; j < numCtl; j++){ /* step through the controls */
- scrn += 4; /* 1 for the csCode, 1 for the length, 2 for the paramBlkPtr. */
- }
- }
- }
- ReleaseResource(screens);
- UseResFile(oldRef);
- }
-
- static pascal void MyMenuHook()
- /* -> nothing is passed in. MenuHook to see if the "P" key is down. This will make the
- change permanent.
- <- nothing is returned.
- */
- { Cursor handCurs;
- EventRecord e;
- Boolean r;
-
- SetUpA4();
- if (keyIsDown(kTempPerm)){
- StuffHex(&handCurs, gCursStr);
- SetCursor(&handCurs);
- gTempPerm = TRUE;
- }else{
- InitCursor();
- gTempPerm = FALSE;
- }
- r = CallPascalB(everyEvent, &e, gOldGNETrap);
- RestoreA4();
- }
-
- static AddDepth(MenuHandle m, short depth, short *total, short *curBit)
- /* -> m is a handle to our popupMenu that we are adding depths to. depth is the depth we wish
- to add to the menu. total is total number of depth items added to the menu thus far.
- curBit is the item number in the menu of the current bit for this gDevice.
- <- nothing is returned.
- */
- { Str255 theStr;
-
- if (HasDepth(gCurGDev, depth, kFlagCnt, kColor) || HasDepth(gCurGDev, depth, kFlagCnt, kBW)){ /* Does the monitor have this depth in color or b&w */
- NumToString((long)depth, theStr); /* yes, then convert the number to a string. */
- pStrcat(theStr, gBitStr); /* append the word Bit to the item */
- AppendMenu(m, theStr); /* add it to the menu */
- *total += 1; /* increment the counter */
- if (*curBit == depth){ /* is this the bit of the current setting */
- *curBit = CountMItems(m); /* find out its' real index in the menu. */
- CheckItem(m, *curBit, 1); /* and check the item in the menu. */
- }
- }
- }
-
- static DoPatch(EventRecord *theEvt)
- /* -> theEvt. theEvt gives us some info as to what has occured. This porcedure will handle
- the building of the popup on the file, and will respond to the actions assoc. with that
- menus item list.
- <- returns nothing
- */
- { short selectedItem, currentDepth;
- long selectedDepth = 1;
- MenuHandle fMenu;
- Str255 theStr;
- short itemPosition = 0, numDepths = 0, modePosition;
- long *theMenuHook;
- long saveMHook;
- Handle oldMBar;
- GrafPtr port;
- char process = FALSE, currentMode;
-
- GetPort(&port);
- if (fMenu = NewMenu(kFlipMenuID, nullStr)){
- HNoPurge(fMenu);
- GetColors(¤tMode, ¤tDepth); /* currentMode : FALSE=gray, TRUE=color; currentDepth = pixeldepth */
- itemPosition = currentDepth;
- AddDepth(fMenu, 1, &numDepths, &itemPosition); /* Check for some depths */
- AddDepth(fMenu, 2, &numDepths, &itemPosition); /* If you needed, then this the place where you */
- AddDepth(fMenu, 4, &numDepths, &itemPosition); /* would add different depths. */
- AddDepth(fMenu, 8, &numDepths, &itemPosition);
- AddDepth(fMenu, 15, &numDepths, &itemPosition);
- AddDepth(fMenu, 16, &numDepths, &itemPosition);
- AddDepth(fMenu, 24, &numDepths, &itemPosition);
- AddDepth(fMenu, 32, &numDepths, &itemPosition);
- AppendMenu(fMenu, gMenuStr); /* add the Grays and Colors items to the menu */
- modePosition = (currentMode*1)+numDepths+2;
- CheckItem(fMenu, modePosition, 1); /* relative to the menu */
- if (currentDepth == 1){ /* if we are in b & w */
- DisableItem(fMenu, numDepths+2);
- DisableItem(fMenu, numDepths+3);
- }
- oldMBar = GetMenuBar();
- InsertMenu(fMenu, kbeforeID);
- if (gCursStr[0] != 0){
- theMenuHook = (long *)kMenuHook;
- saveMHook = *theMenuHook; /* Install the menu hook to our */
- *theMenuHook = (long)&MyMenuHook; /* call back procedure */
- }
- gTempPerm = FALSE;
- if (selectedItem = LoWord(PopUpMenuSelect(fMenu, theEvt->where.v, theEvt->where.h, itemPosition))){
- if ((selectedItem <= numDepths) && (selectedItem != itemPosition)){
- process = TRUE;
- itemPosition = selectedItem;
- }else
- switch (selectedItem - (numDepths+1)){
- case 1: /* chose gray from the menu */
- case 2: /* chose color */
- if (selectedItem != modePosition){
- currentMode = currentMode ? kBW : kColor;
- process = TRUE;
- }
- break;
- }
-
- if (process){
- GetItem (fMenu, itemPosition, theStr);
- theStr[0] -= kLeading;
- StringToNum(theStr, &selectedDepth);
- if (SetDepth(gCurGDev, (short)selectedDepth, kFlagCnt, (short)currentMode) == 0)
- if (gPrefs.isPerm || gTempPerm )
- MakePerm((short)selectedDepth ,currentMode);
- }
- }
- InitCursor();
- if (gCursStr[0] != 0)
- *theMenuHook = saveMHook;
- DeleteMenu(kFlipMenuID);
- SetMenuBar(oldMBar);
- DisposeMenu(fMenu);
- }
- SetPort(port);
- }
-
- static void ShowInit(short theID)
- /* -> theID is the CICN or ICN# ID to show at start up. The procedure was compiled with MPW Asm
- to a 'proc' resource and called directly with CallPascal.
- ShowINITCredits:
- ShowINIT by Paul Mercer
- Copyright 1987-1988
- Version of 7/15/88
- <- returns nothing
- */
- { Handle theRes;
-
- if(theRes = Get1Resource('proc', kShowID)){
- MoveHHi(theRes);
- HLock(theRes);
- CallPascal(theID, kbeforeID, *theRes);
- HUnlock(theRes);
- ReleaseResource(theRes);
- }
- }
- /**********************************************************************************************/
- /* Public Routines for PixelFlipper */
- /**********************************************************************************************/
- pascal char NewGNETrap(short theMask, EventRecord *theEvent)
- /* -> theMask, theEvent are standard arguments passed to GetNextEvent(). Checks to see if
- an event that we must respond to has occured and one of our windows is not active, if
- both these occur, then we DoPatch.
- <- returns char which tells if an event was available.
- */
- { char theVal;
-
- SetUpA4();
- theVal = CallPascalB(theMask, theEvent, gOldGNETrap);
- if (gPrefs.active && (theEvent->what == mouseDown) && (theEvent->modifiers == gPrefs.hotKey)){
- DoPatch(theEvent);
- theVal = FALSE;
- }
- RestoreA4();
- return theVal;
- }
-
- pascal char NewWNETrap( short theMask, EventRecord *theEvent, unsigned long sleep, RgnHandle mouseRgn )
- /* -> theMask, theEvent, sleep, mouseRgn are standard arguments passed to WaitNextEvent().
- Checks to see if an event that we must respond to has occured and one of our windows
- is not active, if both these occur, then we DoPatch.
- <- returns char which tells if an event was available.
- */
- { char theVal;
-
- SetUpA4();
- theVal = CallPascalB( theMask, theEvent, sleep, mouseRgn, gOldWNETrap );
- if (gPrefs.active && (theEvent->what == mouseDown) && (theEvent->modifiers == gPrefs.hotKey)){
- DoPatch(theEvent);
- theVal = FALSE;
- }
- RestoreA4();
- return theVal;
- }
-
- void main()
- { Handle myHandle;
- Ptr myPtr;
- SysEnvRec myEnv;
- hdrPtr h;
- short cnt, i;
-
- asm{
- move.l A0, myPtr /* The address of our INIT is */
- } /* stored in A0 upon entry. */
- RememberA0(); /* So we can access our globals*/
- SetUpA4();
- myHandle = RecoverHandle(myPtr); /* Get a handle to ourself and */
- DetachResource(myHandle); /* detach ourselves. */
- SysEnvirons (curSysEnvVers,&myEnv); /* Get some system info. */
- ClearPointer(&gPrefs, sizeof(PREFRec)); /* make sure the variable is cleared.*/
- if (!myEnv.hasColorQD || myEnv.systemVersion < 0x0605 || keyIsDown(kBypass) || !Get_Set_Prefs(&gPrefs, myEnv.sysVRefNum, getting)){
- ShowInit(kICNBad); /* We weren't able to do this, */
- return; /* so bail out while we can! */
- }
- asm{
- move.l #sizeof (hdr),D0
- _NewPtr SYS + CLEAR
- move.b D0, MemErr
- beq.s @1
- move.w #kICNBad, -(A7)
- jsr ShowInit
- return
- @1 move.l A0,h ; address of storage
- }
- h->hdrVal = 0xA89F1234; /* universal header bytes so our cdev will be able to communicate */
- h->creator = kOurCreat; /* with our INIT. our creator */
- h->prefs = &gPrefs; /* make it point to global data */
- GetIndString(gBitStr, kStrPixel, kBits);
- if (ResError() != noErr)
- pStrcpy(gBitStr, nullStr);
- GetIndString(gCursStr, kStrPixel, kCurs);
- if (ResError() != noErr)
- pStrcpy(gCursStr, nullStr);
- GetIndString(gMenuStr, kStrPixel, kMenuStr);
- if (ResError() != noErr){
- ShowInit(kICNBad);
- DisposPtr(h);
- return;
- }
- /* Now we can patch some traps */
- gOldGNETrap = NGetTrapAddress( kGNETrap, ToolTrap );
- NSetTrapAddress( NewGNETrap, kGNETrap, ToolTrap ); /* Patch GetNextEvent() */
- if ((gOldWNETrap = NGetTrapAddress( kWNETrap, ToolTrap ))!=NGetTrapAddress( kUNITrap, ToolTrap )) /* is WaitNextEvent() implemented */
- NSetTrapAddress( NewWNETrap, kWNETrap, ToolTrap ); /* Patch WaitNextEvent() */
- if (gPrefs.showIcon)
- ShowInit(kICNGood);
- gCurGDev = GetGDevice();
- RestoreA4();
- }